package com.dwxt.community.service;

import com.dwxt.common.base.*;
import com.dwxt.common.util.*;
import com.dwxt.community.dao.*;
import com.dwxt.community.entity.*;
import com.dwxt.community.entity.vo.*;
import com.dwxt.community.service.feign.*;
import lombok.extern.slf4j.*;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang.*;
import org.springframework.beans.factory.annotation.*;
import org.springframework.cloud.commons.util.IdUtils;
import org.springframework.stereotype.*;
import org.springframework.transaction.annotation.*;

import java.text.NumberFormat;
import java.text.ParseException;
import java.util.*;


@Service
@Slf4j
public class UserService {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private SignService signService;

    @Autowired
    private RedisService redisService;

    @Autowired
    private IntegralService integralService;

    @Autowired
    private AsyncService asyncService;

    @Autowired
    private CommunityMapper communityMapper;

    public User login(String phone, String password) {
        User user = selectByPhone(phone);
        return user != null && MD5Utils.MD5Encode(password).equalsIgnoreCase(user.getPassword()) ? user : null;
    }

    public User selectByPhone(String phone) {
        UserExample example = new UserExample();
        example.createCriteria().andPhoneEqualTo(phone);
        List<User> users = userMapper.selectByExample(example);
        return users.size() > 0 ? users.get(0) : null;
    }

    @Transactional
    public BaseResult create(UserVO userVO) {
        BaseResult baseResult = redisService.get(userVO.getPhone());
        if (baseResult == null || baseResult.getStatus() != 200 || !userVO.getCode().equalsIgnoreCase(baseResult.getData().toString())) {
            return BaseResult.build(StatusCode.CODE_ERROR);
        } else {
            //判断是否注册过
            User select = selectByPhone(userVO.getPhone());
            if (select != null) {
                return BaseResult.build(StatusCode.USERNAME_EXIST);
            }
            //查询注册赠送积分
            IntegralRule integralRule = integralService.selectRuleByCategory(IntegralCategory.REGISTER);
            User user = new User();
            user.setIntegral(integralRule.getIntegral());
            user.setId(IDUtils.genItemId());
            user.setPhone(userVO.getPhone());
            user.setPassword(MD5Utils.MD5Encode(userVO.getPassword()));
            user.setIsNameAuthentication(YesOrNo.NO);
            //user.setDongMeiId(dongMeiUserId);
            userMapper.insertSelective(user);

            //积分记录
            integralService.createIntegralRecord(IntegralCategory.REGISTER, integralRule.getIntegral(), user.getId(),
                    null);

            //异步动美场馆注册
            asyncService.dongMeiRegisterAndLogin(user.getId(), userVO.getPhone(), userVO.getPassword());

            return BaseResult.ok();
        }
    }


    public BaseResult resetPassword(UserVO userVO) {
        BaseResult baseResult = redisService.get(userVO.getPhone());
        if (baseResult.getStatus() != 200 || !userVO.getCode().equalsIgnoreCase(baseResult.getData().toString())) {
            return BaseResult.build(StatusCode.CODE_ERROR);
        } else {
            User select = selectByPhone(userVO.getPhone());
            if (select == null) {
                return BaseResult.build(StatusCode.USER_NOT_EXIST);
            }
            select.setPassword(MD5Utils.MD5Encode(userVO.getPassword()));
            userMapper.updateByPrimaryKeySelective(select);
            return BaseResult.ok();
        }
    }

    @Transactional
    public BaseResult sign() {
        String userId = PartyUtil.getCurrentUserId();
        //boolean isSignToday=signService.isSignToday(userId);
        User user = userMapper.selectByPrimaryKey(userId);
        Date now = new Date();
        boolean isSignToday = user.getLastSignTime() != null && DateUtils.isSameDate(now, user.getLastSignTime());
        if (isSignToday) {
            return BaseResult.build(StatusCode.SIGNED_TODAY);
        } else {
            //boolean isContinueDay=DateUtils.isContinueDay(user.getLastSignTime(),new Date());
            Object data = redisService.get("Sign_" + userId).getData();
            Integer integral;
            String category;
            //是否连续签到
            boolean continueDay = user.getLastSignTime() != null && DateUtils.isContinueDay(user.getLastSignTime(),
                    new Date());
            if (continueDay && data != null && Integer.parseInt(data.toString()) >= 7) {
                IntegralRule integralRule = integralService.selectRuleByCategory(IntegralCategory.CONTINUE_SIGN);
                integral = integralRule.getIntegral();
                category = IntegralCategory.CONTINUE_SIGN;
                redisService.set("Sign_" + userId, String.valueOf(Integer.parseInt(data.toString()) + 1), 48 * 60 * 60L);
            } else {
                IntegralRule integralRule = integralService.selectRuleByCategory(IntegralCategory.SIGN);
                integral = integralRule.getIntegral();
                category = IntegralCategory.SIGN;
                if (continueDay && data != null) {
                    //log.error("{}，签到出现未知错误", userId);
                    redisService.set("Sign_" + userId, String.valueOf(Integer.parseInt(data.toString()) + 1),
                            48 * 60 * 60L);
                } else {
                    redisService.set("Sign_" + userId, "1", 48 * 60 * 60L);
                }
            }
            //更改上次签到时间,加积分
            user.setLastSignTime(now);
            user.setIntegral(user.getIntegral() + integral);
            userMapper.updateByPrimaryKeySelective(user);
            //积分记录
            integralService.createIntegralRecord(category, integral, userId, null);
            //新增一条签到记录
            signService.create(userId);
            return BaseResult.ok(user);
        }
    }


    public List<SignRecord> selectSignRecordList() {
        String currentUserId = PartyUtil.getCurrentUserId();
        return signService.getSignRecord(currentUserId);
    }

    public BaseResult update(User user) {
        String userId = PartyUtil.getCurrentUserId();
        User userCard = selectByIDCard(user.getIdentityCard());
        if (userCard != null && !userCard.getId().equalsIgnoreCase(userId)) {
            return BaseResult.build(StatusCode.ID_CARD_EXIST);
        }
        //只有第一次完善信息才加积分
        User key = userMapper.selectByPrimaryKey(userId);
        if (StringUtils.isBlank(key.getIdentityCard())) {
            //增加积分
            IntegralRule integralRule = integralService.selectRuleByCategory(IntegralCategory.COMPLETE__INFORMATION);
            user.setIntegral(key.getIntegral() + integralRule.getIntegral());
            //积分记录
            integralService.createIntegralRecord(IntegralCategory.COMPLETE__INFORMATION, integralRule.getIntegral(),
                    userId, null);
        }
        if (StringUtils.isNotBlank(user.getIdentityCard())) {
            user.setIsNameAuthentication(YesOrNo.YES);
        }
        //如果更改地址，取消户主
        if (key.getIsHouseHead() == YesOrNo.YES) {
            if (!key.getCommunityName().equalsIgnoreCase(user.getCommunityName()) || !key.getHouseNumber().equalsIgnoreCase(user.getHouseNumber())) {
                user.setIsHouseHead(YesOrNo.NO);
            }
        }
        user.setId(userId);
        userMapper.updateByPrimaryKeySelective(user);
        return BaseResult.ok();
    }

    public User selectByIDCard(String identityCard) {
        UserExample example = new UserExample();
        example.createCriteria().andIdentityCardEqualTo(identityCard);
        List<User> userList = userMapper.selectByExample(example);
        return userList.size() > 0 ? userList.get(0) : null;
    }

    public int updatePassword(String oldPassword, String newPassword) {
        String userId = PartyUtil.getCurrentUserId();
        User user = userMapper.selectByPrimaryKey(userId);
        if (MD5Utils.MD5Encode(oldPassword).equals(user.getPassword())) {
            user.setPassword(MD5Utils.MD5Encode(newPassword));
            return userMapper.updateByPrimaryKeySelective(user);
        }
        return 0;
    }

    public User selectCurrUserByPrimaryKey() {
        String userId = PartyUtil.getCurrentUserId();
        return userMapper.selectByPrimaryKey(userId);
    }

    public User selectUserByPrimaryKey(String userId) {
        return userMapper.selectByPrimaryKey(userId);
    }

    @Transactional
    public BaseResult updateIntegral(Integer integral, String relateId, String category, String userId) {
        if (StringUtils.isBlank(userId)) {
            userId = PartyUtil.getCurrentUserId();
        }
        User user = userMapper.selectByPrimaryKey(userId);

        //其他服务加积分
        if (integral == null) {
            IntegralRule integralRule = integralService.selectRuleByCategory(category);
            if (integralRule.getCountLimit() != 0) {
                int count = integralService.countTodayByCategoryAndUserId(category, userId);
                if (count >= integralRule.getCountLimit()) {
                    return BaseResult.ok();
                }
            }
            integral = integralRule.getIntegral();
        }
        user.setIntegral(user.getIntegral() + integral);
        userMapper.updateByPrimaryKeySelective(user);

        integralService.createIntegralRecord(category, integral, userId, relateId);
        return BaseResult.ok(user);
    }

    /**
     * 拼接家庭地址
     *
     * @param user
     * @return
     */
    public String getHouseAddr(User user) {
        return user.getCommunityId() + "," + user.getCommunityName() + "," + user.getHouseNumber();
    }


    @Transactional
    public void confirmHouseHead(String id) {
        User user = userMapper.selectByPrimaryKey(id);
        if (user.getIsHouseHead() == YesOrNo.NO) {
            //更改户主
            User header = userMapper.selectHouseOwnerByUserId(id);
            if (header != null) {
                header.setIsHouseHead(YesOrNo.NO);
                userMapper.updateByPrimaryKeySelective(header);
            }
            user.setIsHouseHead(YesOrNo.YES);
            userMapper.updateByPrimaryKeySelective(user);
        }
    }


    public User selectByPrimaryKey(String userId) {
        return userMapper.selectByPrimaryKey(userId);
    }

    public BaseResult updatePhone(UserVO userVO) {
        BaseResult baseResult = redisService.get(userVO.getPhone());
        if (baseResult.getStatus() != 200 || !userVO.getCode().equalsIgnoreCase(baseResult.getData().toString())) {
            return BaseResult.build(StatusCode.CODE_ERROR);
        } else {
            User user = selectCurrUserByPrimaryKey();
            if (user.getPassword().equalsIgnoreCase(MD5Utils.MD5Encode(userVO.getPassword()))) {
                User byPhone = selectByPhone(userVO.getPhone());
                if (byPhone != null) {
                    return BaseResult.build(StatusCode.USERNAME_EXIST);
                }
                user.setPhone(userVO.getPhone());
                userMapper.updateByPrimaryKeySelective(user);
                return BaseResult.ok();
            } else {
                return BaseResult.build(StatusCode.USERNAME_PASSWORD_WRONG);
            }
        }
    }

    /**
     * 获取户主
     *
     * @return
     */
    public User selectHouseOwnerByUserId(String id) {
        return userMapper.selectHouseOwnerByUserId(id);
    }

    /**
     * 更新户主
     *
     * @param user
     * @return
     */
    public int updateHouseOwner(User user) {
        return userMapper.updateByPrimaryKeySelective(user);
    }

    public void updateHeadPicture(String headPhotoUrl) {
        if (headPhotoUrl.startsWith("http")) {
            User user = new User();
            user.setId(PartyUtil.getCurrentUserId());
            user.setHeadPhotoUrl(headPhotoUrl);
            userMapper.updateByPrimaryKeySelective(user);
        }
    }

    public BaseResult selectTotal() {
        HashMap<String, Object> map = new HashMap<>();
        //总知晓率
        String know = userMapper.selectAwareness();
        map.put("总知晓率", know);
        //总用户
        int totalUserNum = userMapper.selectTotalUsers();
        map.put("总用户数", totalUserNum);
        //总参与率
        String participation = userMapper.selectTotalParticipation();
        map.put("总参与率", participation);
        return BaseResult.ok(map);
    }

    /**
     * 各个街道参与情况表
     *
     * @return
     */
    public BaseResult selectTotalByStreetList() {
        List<CommunityVo> communities = communityMapper.selectCommnityVo();
        ArrayList<HashMap> hashMaps = new ArrayList<>();
        for (CommunityVo community : communities) {
            HashMap<String, Object> map = new HashMap<>();
            Integer id = community.getId();
            //知晓率
            map.put("知晓率", community.getKnown());
            //用户
            int totalUserNum = userMapper.selectTotalUsersByCommunityId(id);
            map.put("用户数", totalUserNum);
            //参与率
            map.put("参与率", community.getParticipation());
            map.put("准确率", community.getAccuracy());
            map.put("小区名", community.getCommunityName());
            map.put("街道", community.getStreet());
            hashMaps.add(map);
        }
        return BaseResult.ok(hashMaps);
    }

    //后台手动创建用户
    public BaseResult createUser(User user) {
        User selectByPhone = selectByPhone(user.getPhone());
        if (selectByPhone != null) {
            return BaseResult.build(StatusCode.USERNAME_EXIST);
        }
        User selectByIDCard = selectByIDCard(user.getIdentityCard());
        if (selectByIDCard != null) {
            return BaseResult.build(StatusCode.ID_CARD_EXIST);
        }
        //selectHouseOwnerByUserId()
        user.setId(IDUtils.genItemId());
        String password = IDUtils.genItemId();
        user.setPassword(MD5Utils.MD5Encode(password));
        user.setIsNameAuthentication(YesOrNo.YES);
        userMapper.insertSelective(user);
        asyncService.dongMeiRegisterAndLogin(user.getId(), user.getPhone(), password);
        return BaseResult.ok(user);
    }

    public Integer countUserByCreateTime(String date) {
        return userMapper.countUserByCreateTime(date);
    }

    public void updateLastLoginTime(String userId) {
        User user = new User();
        user.setId(userId);
        user.setLastLoginTime(new Date());
        userMapper.updateByPrimaryKeySelective(user);
    }

    public BaseResult selectUserCount(String date) throws ParseException {
        UserExample example = new UserExample();
        if (StringUtils.isNotBlank(date)) {
            example.createCriteria().andCreateTimeLessThan(DateUtils.formatDate(date));
        }
        long count = userMapper.countByExample(example);
        return BaseResult.ok(count);
    }
}
